import time
import logging
log = logging.getLogger(__name__)

from crv.model.crvmodel import *
from crv.model.rp import *

from sqlalchemy.orm import mapper
from sqlalchemy.orm import relation, backref

import pickle

class DummyVMMaker(VMMaker):
    def __init__(self):
        super(DummyVMMaker, self).__init__("dummy")
        
        self.debug("DummyVMMaker::__init__(%s)"%self.vmtype)
        self.runningvms={}
        self.counter=0
        self.stoptime={}
        self.filename="/tmp/dummyvmmaker"

        try:
            self.load()
        except:
            self.save()

    def debug(self,str):
        print str
        
    def save(self):
        ouf=open(self.filename,"w")
        pickle.dump(self.runningvms,ouf)
        pickle.dump(self.counter,ouf)
        pickle.dump(self.stoptime,ouf)
        ouf.close()

    def load(self):
        inf=open(self.filename,"r")
        self.runningvms=pickle.load(inf)
        self.counter=pickle.load(inf)
        self.stoptime=pickle.load(inf)
        inf.close()

    def persist(foo):
        def magic(self,*args, **kwargs):
            print "loading..."
            self.load()
            result=foo(self,*args, **kwargs)
            print "saving..."
            self.save()
            return result
        return magic

    @persist
    def ready(self):
        return True

    @persist
    def powerOn(self):
        self.counter=self.counter+1
        vmnumber=self.counter
        self.runningvms[str(vmnumber)]=True
        self.debug("DummyVMMaker:poweronVM called, starting dummy vmuuid=%s"%str(vmnumber))
        self.debug("runningvms=%s"%str(self.runningvms))
        return str(vmnumber)

    @persist
    def powerOff(self,identifier):
        self.debug("DummyVMMaker:poweroffVM called: identifier=%s, runningvms=%s"%(identifier,str(self.runningvms)))
        if self.runningvms.has_key(identifier) and self.runningvms[identifier]==True:
            if self.stoptime.has_key(identifier):
                if time.mktime(time.gmtime())-self.stoptime[identifier]>25:
                    self.stoptime.pop(identifier)
                    self.runningvms.pop(identifier)
                    self.debug("DummyVMMaker::powerOff::already stopped: identifier=%s"%identifier)                    
                    return
                else:
                    self.debug("DummyVMMaker::powerOff::still stopping: identifier=%s, time.mktime(time.gmtime())-self.stoptime[identifier]=%d"%(identifier,time.mktime(time.gmtime())-self.stoptime[identifier]))
                    return
            else:
                self.stoptime[identifier]=time.mktime(time.gmtime())
        else:
            raise RuntimeError("DummyVMMaker:trying to poweroff a non-started VM (identifier=%s)"%identifier)
        self.debug("runningvms=%s"%str(self.runningvms))

    @persist
    def isStarting(self,identifier):
        #concept of isStarting in VMMaker and VMMgr are different. VMMgr need to wait for the signal of self test (Started=True) in addition to here
        #always return false, since the vm is considered started after powerOn
        return False

    @persist
    def isStarted(self,identifier):
        return self.runningvms.has_key(identifier) and not self.stoptime.has_key(identifier)

    @persist
    def isStopped(self,identifier):
        self.debug("DummyVMMaker::isStopped: called: identifier=%s, runningvms=%s"%(identifier,str(self.runningvms)))
        self.debug("DummyVMMaker::isStopped: self.runningvms.has_key(identifier)=%s"%str(self.runningvms.has_key(identifier)))        
        if self.runningvms.has_key(identifier) and self.runningvms[identifier]==True:
            if self.stoptime.has_key(identifier):
                if time.mktime(time.gmtime())-self.stoptime[identifier]>25:
                    self.stoptime.pop(identifier)
                    self.runningvms.pop(identifier)
                    self.debug("DummyVMMaker::isStoppedalready stopped: identifier=%s"%identifier)                    
                    return True
                else:
                    self.debug("DummyVMMaker::isStoppedstill stopping: identifier=%s, time.mktime(time.gmtime())-self.stoptime[identifier]=%d"%(identifier,time.mktime(time.gmtime())-self.stoptime[identifier]))
                    return False
            else:
                self.debug("DummyVMMaker::isStopped: should be running, return false")
                return False
        self.debug("DummyVMMaker::isStopped:already stopped or not running: identifier=%s"%identifier)
        return True
    
    @persist
    def isStopping(self,identifier):
        self.debug("DummyVMMaker::isStoppingisStopping called: identifier=%s, runningvms=%s"%(identifier,str(self.runningvms)))
        if self.runningvms.has_key(identifier) and self.runningvms[identifier]==True:
            if self.stoptime.has_key(identifier):
                if time.mktime(time.gmtime())-self.stoptime[identifier]>25:
                    self.stoptime.pop(identifier)
                    self.runningvms.pop(identifier)
                    self.debug("DummyVMMaker::isStoppingalready stopped: identifier=%s"%identifier)                    
                    return False
                else:
                    self.debug("DummyVMMaker::isStoppingstill stopping: identifier=%s, time.mktime(time.gmtime())-self.stoptime[identifier]=%d"%(identifier,time.mktime(time.gmtime())-self.stoptime[identifier]))
                    return True
            else:
                self.debug("DummyVMMaker::isStopping: should be running, return false")
                return False
        self.debug("DummyVMMaker::isStoppingalready stopped or not running: identifier=%s"%identifier)
        return False
    

    @persist
    def getIdentifiers(self):
        return self.runningvms


